186. istio的Authorization policy(白名單)

前言

經過一個月的搬家事宜,
這篇應該是第一篇,之後還有許多東西,
都是這個月搬project碰到的。

正文

目的

只要設定白名單,限制某些ip能進入就好,
其他不用。

實作-Network

這邊使用istio 1.20 版本,雖然gateway API 剛出爐,
但我還沒去研究,所以下面用的都還是 istio API

首先確認你的LB類型,
直連(Network)的話,基本上沒太大問題,白名單很好設定。

  1. 開啓 externalTrafficPolicy":"Local"
    兩種方法

    a. 手動改service

   kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}'

b. 加在istioOperator上面

ingressGateways:
    - name: istio-ingressgateway    
      enabled: true
      k8s: 
        service:
          externalTrafficPolicy: Local
          loadBalancerSourceRanges:
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
  1. Authorization設定
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: manage-ingress-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  action: ALLOW
  rules:
  - from:
    - source:
        ipBlocks:: 
          - "10.0.0.0/8"
          - "172.16.0.0/12"
          - "192.168.0.0/16"   

(注意,這邊的Load Balancer Type指的是Network,沒透過proxy的,
如果有開CDN,那就是istio說明上面的Load Balancer Type 是TCP Proxy)

ref. Ingress Access Control

實作-Proxy

這邊的網路走法是,有透過CDN,或是其他的prxoy代理連過來的服務。
numTrustedProxies 這個的值,取決於你的走法過了幾層的proxy,
我只有cdn轉島到gke上面的istio LB

  1. 設定方式

    a. 在pod上面新增 anntations

  metadata:
    annotations:
      "proxy.istio.io/config": '{"gatewayTopology" : { "numTrustedProxies": 1 } }'

b. 在istioOperator新增

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      gatewayTopology:
        numTrustedProxies: 1	
  1. Authorization設定

這邊有點坑,搞了一天才搞清楚。
強烈建議把istio的httpbin裝起來,實際去打,
然後一邊查看ingressgateway的deployment的log。

a. 限制全部

這是第一種方法,但這個只能針對『入口』的ingress做白名單驗證。

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
 name: frontend-ingress-policy
 namespace: istio-system
spec:
 selector:
   matchLabels:
     app: ingressgateway-external
 action: ALLOW
 rules:
 - from:
   - source:
       remoteIpBlocks: 
         - "10.0.0.0/8"
         - "172.16.0.0/12"
         - "192.168.0.0/16"

b. 針對單個
假如沒有在入口的話,無法照上面a.的方式抓到資料,
所以只能強制指定判斷header。
ref. Incorrect RemoteIP when Authorization Policy is applied to Injected Istio Proxy

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: frontend-ingress-policy
spec:
  selector:
    matchLabels:
      group: frontend
  action: ALLOW
  rules:
    - when:
        - key: request.headers[X-Envoy-External-Address]
          values:
            - "10.*"

ref. Configuring Gateway Network Topology

Troubleshooting

istioOperator增加log 閱讀性
spec:
  meshConfig:
    accessLogFile: /dev/stdout
    accessLogEncoding: JSON
    accessLogFormat: |
      {
        "protocol": "%PROTOCOL%",
        "upstream_service_time": "%REQ(X-ENVOY-UPSTREAM_SERVICE_TIME)%",
        "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%",
        "duration": "%DURATION%",
        "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%",
        "route_name": "%ROUTE_NAME%",
        "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%",
        "user_agent": "%REQ(USER-AGENT)%",
        "response_code": "%RESPONSE_CODE%",
        "response_flags": "%RESPONSE_FLAGS%",
        "start_time": "%START_TIME%",
        "method": "%REQ(:METHOD)%",
        "request_id": "%REQ(X-REQUEST-ID)%",
        "upstream_host": "%UPSTREAM_HOST%",
        "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%",
        "client_ip": "%REQ(TRUE-Client-IP)%",
        "requested_server_name": "%REQUESTED_SERVER_NAME%",
        "bytes_received": "%BYTES_RECEIVED%",
        "bytes_sent": "%BYTES_SENT%",
        "upstream_cluster": "%UPSTREAM_CLUSTER%",
        "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%",
        "authority": "%REQ(:AUTHORITY)%",
        "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%",
        "response_code_details": "%RESPONSE_CODE_DETAILS%"
      }

ref. Understanding Istio Access Logs

Authorization Policy規則
  1. If there are any CUSTOM policies that match the request, evaluate and deny the request if the evaluation result is deny.

    如果有任何符合請求的自訂策略,則評估並拒絕請求,若評估結果為拒絕。

  2. If there are any DENY policies that match the request, deny the request.

    如果有符合請求的任何拒絕策略,則拒絕該請求。

  3. If there are no ALLOW policies for the workload, allow the request.

    如果工作負載沒有任何允許策略,則允許該請求。

  4. If any of the ALLOW policies match the request, allow the request.

    如果有任何允許策略符合該請求,則允許該請求。

  5. Deny the request.

    拒絕該請求。

ref. Authorization Policy

cloudflare轉發

上面有提到用cloudflare的CDN時,白名單會跟着變,
但在那之前還有個東西要注意,CDN轉發時,
cloudflare可以指定走http還是走https
這個會影響到istio的gateway,是開80還是443。
186-fig.1.jpg